package com.yg.edu.lock;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.LockSupport;

/**
 * @author ：杨过
 * @date ：Created in 2020/4/28
 * @version: V1.0
 * @slogan: 天下风云出我辈，一入代码岁月催
 * @description:
 **/
@Slf4j
public class Juc01_Thread_LockSupport {
    /**
     * unpark可以唤醒，release
     * interrupt会把线程唤醒队列头部的线程，打一个标记位interruted标记，默认为false，线程被中断过就interruted标记为true
     *  Thread.interrupted()会把jdk里的interruted标记清除掉，中断标志没了，线程是被中断唤醒的，外面需要感知到被擦除，所以需要在acquire出selfInterrupt()

     *Thread.currentThread.interrupted()就是打个标记告诉线程是怎么被唤醒的
     *
     * park(Object)  只会唤醒一次，下次还会阻塞当前线程
     * park() 无参的这个方法  一旦被唤醒 park再也不会阻塞它
     * aqs使用的是park(Object) 只会唤醒一次
     *
     * @param args
     */
    public static void main(String[] args) {

        Thread t0 = new Thread(new Runnable() {
            @Override
            public void run() {
                Thread current = Thread.currentThread();
                log.info("{},开始执行!",current.getName());
                for(;;){//spin 自旋
                    log.info("准备park住当前线程：{}....",current.getName());
                    LockSupport.park();
                    System.out.println("是否中断："+Thread.interrupted());
                    log.info("当前线程{}已经被唤醒....",current.getName());

                }
            }
        },"t0");

        t0.start();

        try {
            Thread.sleep(2000);
            log.info("准备唤醒{}线程!",t0.getName());
            LockSupport.unpark(t0);
            Thread.sleep(2000);
            t0.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
